package com.shockweb.common.utils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;

import com.shockweb.common.International;
import com.shockweb.common.serializable.SerializableObject;
/**
 * 文件操作工具类
 * @author pengmh
 *
 */
public class FileTools {
	

	
	/**
	 * 读取的缓存区
	 */
	private static int readSize=1024;
	
	/**
	 * 设置读取文件的buffer大小
	 * @param readSize
	 */
	public static void setReadSize(int readSize){
		FileTools.readSize = readSize;
	}
	
	/**
	 * 获取当前Class所在的路径
	 * @return String
	 */
	public static String getClassPath(){
		if(Class.class.getClass().getResource("/")!=null) {
			return Class.class.getClass().getResource("/").getPath();
		}else if(Class.class.getClass().getResource("")!=null) {
			return Class.class.getClass().getResource("").getPath();
		}else if(Thread.currentThread().getContextClassLoader().getResource("")!=null) {
			return Thread.currentThread().getContextClassLoader().getResource("").getPath();
		}else if(ClassLoader.getSystemResource("")!=null) {
			return ClassLoader.getSystemResource("").getPath();
		}else{
			return null;
		}
	}

	/**
	 * 获得完整路径
	 * @param path
	 * @param name
	 * @return String
	 */
	public static String getFullPathFileName(String path,String name){
		String root = "//";
		if(name.startsWith(root)){
			return name.substring(root.length(),name.length());
		}else{
			if(path.endsWith("/")){
				if(name.startsWith("/")){
					return path.substring(0,path.length()-"/".length()) + name;
				}else{
					return path + name;
				}
			}else{
				if(name.startsWith("/")){
					return path + name;
				}else{
					return path + "/" + name;
				}
			}
		}
	}
	
	/**
	 * 复制文件
	 * @param source
	 * @param target
	 * @throws IOException
	 */
	public static void copy(String source,String target) throws IOException{
		FileInputStream s = null;
		FileOutputStream t = null;
		try{
			s = new FileInputStream(source);
			t = new FileOutputStream(target);
			if(readSize<=0){
				readSize = 1024;
			}
			int realReadSize = readSize;
			byte[] data = new byte[readSize];
	    	while(realReadSize>0){
	    		realReadSize = s.read(data);
	    		if(realReadSize>0){
	    			t.write(data,0,realReadSize);
	    		}
	    	}
		}finally{
			try{
				if(s!=null)s.close();
			} catch (IOException e) {
			}
			try{
				if(t!=null)t.close();
			} catch (IOException e) {
			}
		}
	}
	
	/**
	 * 读取文件数据
	 * @param filename
	 * @return byte[]
	 * @throws IOException
	 */
	public static byte[] read(String filename) throws IOException{
		FileInputStream f = null;
		try{
			f = new FileInputStream(filename);
			return read(f);
		}finally{
			try{
				if(f!=null)f.close();
			} catch (IOException e) {
			}
		}
	}
	
	/**
	 * 读取文件数据
	 * @param filename
	 * @param index
	 * @param len
	 * @return byte[]
	 * @throws IOException
	 */
	public static byte[] read(String filename,int index,int len) throws IOException{
		
		RandomAccessFile in = null;
		try{
			List<byte[]> buffer = new ArrayList<byte[]>();
			if(readSize<=0){
				readSize = 1024;
			}
			int realReadSize = readSize;
			in=new RandomAccessFile(filename, "r");
			in.seek(index);
			long currReadSize = len;
			int realSize = 0;
			while(realReadSize>0 && currReadSize>0){
	    		byte[] data = new byte[readSize>currReadSize?readSize:(int)currReadSize];
	    		realReadSize = in.read(data);
	    		if(realReadSize>0){
	    			buffer.add(data);
		    		currReadSize -= realReadSize;
		    		realSize += realReadSize;
	    		}
	        }  
			if(realSize>0){
				int j = 0;
				byte[] rtn = new byte[realSize];
		    	for(int i=0;i<buffer.size();i++){
		    		SerializableObject.copyBytes(buffer.get(i),rtn,j);
		    		j = j + buffer.get(i).length;
		    	}
				return rtn;
			}else{
				return null;
			}
		}finally{
			try{
				if(in!=null)in.close();
			} catch (IOException e) {
			}
		}

	}
	
	
	/**
	 * 读取文件数据
	 * @param in
	 * @return String
	 * @throws IOException
	 */
	public static byte[] read(InputStream in) throws IOException{
		List<byte[]> buffer = new ArrayList<byte[]>();
		if(readSize<=0){
			readSize = 1024;
		}
		int realReadSize = readSize;
		int realSize = 0;
    	while(realReadSize>0){
    		byte[] data = new byte[readSize];
    		realReadSize = in.read(data);
    		if(realReadSize>0){
    			buffer.add(data);
    			realSize += realReadSize;
    		}
    	}
		if(realSize>0){
			int j = 0;
			byte[] rtn = new byte[realSize];
	    	for(int i=0;i<buffer.size();i++){
	    		SerializableObject.copyBytes(buffer.get(i),rtn,j);
	    		j = j + buffer.get(i).length;
	    	}
			return rtn;
		}else{
			return null;
		}
	}
	
	/**
	 * 将二进制数据追加写入到文件中
	 * @param filename
	 * @param data
	 * @throws IOException
	 */
	public static void writeAppend(String filename,byte[] data) throws IOException{
		RandomAccessFile f = null;
		try{
			f = new RandomAccessFile(filename,"rw");
			writeAppend(f,data);
		}finally{
			try{
				if(f!=null)f.close();
			} catch (IOException e) {
			}
		}
	}
	
	/**
	 * 将二进制数据追加写入到文件流中
	 * @param out
	 * @param data
	 * @throws IOException
	 */
	public static void writeAppend(RandomAccessFile out,byte[] data) throws IOException{
	    // 文件长度，字节数     
	    long fileLength = out.length();     
	    // 将写文件指针移到文件尾。     
	    out.seek(fileLength);     
	    out.write(data);      
	}
	
	/**
	 * 将二进制数据写入到文件中
	 * @param filename
	 * @param data
	 * @throws IOException
	 */
	public static void write(String filename,byte[] data) throws IOException{
		FileOutputStream f = null;
		try{
			f = new FileOutputStream(filename);
			write(f,data);
		}finally{
			try{
				if(f!=null)f.close();
			} catch (IOException e) {
			}
		}
	}
	
	/**
	 * 将二进制数据写入到文件流中
	 * @param out
	 * @param data
	 * @throws IOException
	 */
	public static void write(OutputStream out,byte[] data) throws IOException{
		out.write(data);
	}
	
	/**
	 * 将文本写入到文件中
	 * @param filename
	 * @param text
	 * @throws IOException
	 */
	public static void writeText(String filename,String text) throws IOException{
		FileOutputStream f = null;
		try{
			f = new FileOutputStream(filename);
			writeText(f,text);
		}finally{
			try{
				if(f!=null)f.close();
			} catch (IOException e) {
			}
		}
	}
	
	/**
	 * 将文本写入到文件中
	 * @param out
	 * @param text
	 * @throws IOException
	 */
	public static void writeText(OutputStream out,String text) throws IOException{
		OutputStreamWriter osWriter = null;
		BufferedWriter writer = null;
		try{
			osWriter = new OutputStreamWriter(out, International.CHARSET);
			writer = new BufferedWriter(osWriter);
			writer.write(text);
		}finally{
			try{
				if(writer!=null)writer.close();
			} catch (IOException e) {
			}
			try{
				if(osWriter!=null)osWriter.close();
			} catch (IOException e) {
			}
		}
	}
	
	/**
	 * 读取文件到String
	 * @param filename
	 * @return String
	 * @throws IOException
	 */
	public static String readText(String filename) throws IOException{
		FileInputStream f = null;
		try{
			f = new FileInputStream(filename);
			return readText(f);
		}finally{
			try{
				if(f!=null)f.close();
			} catch (IOException e) {
			}
		}
	}
	
	/**
	 * 读取文件到String
	 * @param in
	 * @return String
	 * @throws IOException
	 */
	public static String readText(InputStream in) throws IOException{
		StringBuffer rtn = new StringBuffer();
		if(readSize<=0){
			readSize = 1024;
		}
		int realReadSize = readSize;
		byte[] data = new byte[readSize];
    	while(realReadSize>0){
    		realReadSize = in.read(data);
    		if(realReadSize>0)
    			rtn.append(new String(data,0,realReadSize,International.CHARSET));
    	}
		if(rtn.length()>0){
			return rtn.toString();
		}else{
			return null;
		}
	}
	
	/**
	 * 删除文件或目录下所有文件
	 * @param path
	 */
	public  static void deleteAll(String path){
		deleteAll(new File(path));
	}
	
	/**
	 * 删除文件或目录下所有文件
	 * @param path
	 */
	public  static void deleteAll(File path){   
		  if(!path.exists()){
			  return;
		  }
		  if(path.isFile()){   
			  path.delete();   
			  return;
		  }   
		  File[] files = path.listFiles();       
	      for(int   i=0;i<files.length;i++){   
	    	  deleteAll(files[i]);   
	      }   
	      path.delete();   
	}
}
